/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
import dao.DerbyDao;
import electricitysupplier.T1ES1;
import es2service.ClientMeterReading;
import es2service.TestService;
import es2service.TestServiceSoap;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import kr2.Receive;
import kr2.ReceiveDmdFromNO;
import kr2.ReceiveLpFromNo;
import kr2.Receive_Service;
import krado.ElectricityProfile;
import krado.KradoServiceSoap;
import krado.KradoServiceSoapImplService;
import krado.MeterReading;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import service.MeasurementService;

/** 
 *
 * @author Yuuzaa
 */
public class MeasurementController extends SimpleFormController {

    private MeasurementService measurementService;
    private T1ES1 t1Service;
    private Receive k2Service;

    public MeasurementController() {
        //Initialize controller properties here or 
        //in the Web Application Context
        t1Service = new T1ES1();
        k2Service = new Receive_Service().getReceivePort();
        setCommandClass(Measurement.class);
        setCommandName("mName");
        setSuccessView("measurementView");
        setFormView("mNameView");
    }

    //Use onSubmit instead of doSubmitAction 
    //when you need access to the Request, Response, or BindException objects
    @Override
    protected ModelAndView onSubmit(
            HttpServletRequest request,
            HttpServletResponse response,
            Object command,
            BindException errors) throws Exception {
        Measurement measurement = (Measurement) command;
        MeterReading mr = new MeterReading();
        ElectricityProfile ep = new ElectricityProfile();
        DateFormat formatter;
        formatter = new SimpleDateFormat("dd.MM.yyyy");
        DerbyDao dao = new DerbyDao();
        KradoServiceSoap kss = new KradoServiceSoapImplService().getKradoServiceSoapImplPort();
        TestServiceSoap tss = new TestService().getTestServiceSoap();
        if ("Krado1M".equals(measurement.getSendTo())) {
            mr.setAmount(measurement.getReading());
            mr.setContractId(measurement.getContractId());
            GregorianCalendar cal = new GregorianCalendar();
            cal.setTime((Date) formatter.parse(measurement.getStartDate()));
            XMLGregorianCalendar xmlCal = new XMLGregorianCalendarImpl(cal);
            mr.setDate(xmlCal);
            mr.setMessageId("" + dao.getComposedMessageId());
            mr.setNoId("T1NO1");
            kss.reportDailyReading(mr);
            JAXBContext context = JAXBContext.newInstance(MeterReading.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "meterReading"), MeterReading.class, mr), writer);
            dao.insertComposedMessage(writer.toString());
        }
        if ("Krado1LP".equals(measurement.getSendTo())) {
            ep.setAmount(measurement.getConsumption());
            ep.setAreaId(measurement.getAreaId());
            ep.setContractId(measurement.getContractId());
            GregorianCalendar cal = new GregorianCalendar();
            cal.setTime((Date) formatter.parse(measurement.getEndDate()));
            XMLGregorianCalendar xmlCal = new XMLGregorianCalendarImpl(cal);
            ep.setDateEnd(xmlCal);
            ep.setMessageId("" + dao.getComposedMessageId());
            kss.reportProfile(ep);
            JAXBContext context = JAXBContext.newInstance(ElectricityProfile.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "electricityProfile"), ElectricityProfile.class, ep), writer);
            dao.insertComposedMessage(writer.toString());
        }
        if ("Krado2M".equals(measurement.getSendTo())) {
            ReceiveDmdFromNO rdmd= new ReceiveDmdFromNO();
            rdmd.setDMD(measurement.getReading().toString());
            k2Service.receiveDmdFromNO(rdmd.getDMD());
            JAXBContext context = JAXBContext.newInstance(ReceiveDmdFromNO.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "receiveDmdFromNO"), ReceiveDmdFromNO.class, rdmd), writer);
            dao.insertComposedMessage(writer.toString());
        }
        if ("Krado2LP".equals(measurement.getSendTo())) {
            ReceiveLpFromNo rlp = new ReceiveLpFromNo();
            DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            rlp.setLoadEstimation(measurement.getConsumption().toString());
            rlp.setMessageId(""+dao.getComposedMessageId());
            rlp.setMessageRecipient("T1RK2");
            rlp.setMessageSender("T1NO1");
            rlp.setNetworkLoss((int)(Math.random()*10)+"%");
            rlp.setSendTime(dateFormat.format(new Date()));
            k2Service.receiveLpFromNo(rlp.getMessageId(), rlp.getMessageRecipient(), rlp.getSendTime(), rlp.getMessageSender(), rlp.getLoadEstimation(), rlp.getNetworkLoss());
            JAXBContext context = JAXBContext.newInstance(ReceiveLpFromNo.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "receiveLpFromNo"), ReceiveLpFromNo.class, rlp), writer);
            dao.insertComposedMessage(writer.toString());
        }
        if ("ESM1".equals(measurement.getSendTo())) {
            electricitysupplier.MeterReading msgRead = new electricitysupplier.MeterReading();
            GregorianCalendar cal = new GregorianCalendar();
            cal.setTime((Date) formatter.parse(measurement.getStartDate()));
            XMLGregorianCalendar xmlCal = new XMLGregorianCalendarImpl(cal);
            msgRead.setAmount(measurement.getReading());
            msgRead.setContractId(measurement.getContractId());
            msgRead.setDate(xmlCal);
            msgRead.setMessageId("" + dao.getComposedMessageId());
            msgRead.setNoId("T1NO1");
            t1Service.getBasicHttpBindingIT1ES1Service().receiveMeterReading(msgRead);
            JAXBContext context = JAXBContext.newInstance(electricitysupplier.MeterReading.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "msgRead"), electricitysupplier.MeterReading.class, msgRead), writer);
            dao.insertComposedMessage(writer.toString());
        }
        if ("ESM2".equals(measurement.getSendTo())) {
            ClientMeterReading clmr = new ClientMeterReading();
            clmr.setRegistrationCode(""+dao.findRegNumByContract(measurement.getContractId().intValue()));
            clmr.setValue(measurement.getReading().toString());
            JAXBContext context = JAXBContext.newInstance(ClientMeterReading.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "clientMeterReading"), ClientMeterReading.class, clmr), writer);
            dao.insertComposedMessage(writer.toString());
            tss.clientMeterReading(clmr.getRegistrationCode(),clmr.getValue());
        }
        ModelAndView mv = new ModelAndView(getSuccessView());
        mv.addObject("measurementMessage", measurementService.sayResult("Message sent."));
        return mv;
    }
    
    public void setMeasurementService(MeasurementService measurementService) {
        this.measurementService = measurementService;
    }
}
